package router

import (
	"os/exec"
	"path"
	"strings"

	"gitee.com/actor168/gitserver/pkg/config"
	"gitee.com/actor168/gitserver/pkg/repoutil"
	"github.com/gin-gonic/gin"
	"github.com/gogs/git-module"
)

type Repository struct {
	IsWatching   bool
	IsViewBranch bool
	IsViewTag    bool
	IsViewCommit bool
	Commit       *git.Commit
	Tag          *git.Tag
	GitRepo      *git.Repository
	BranchName   string
	TagName      string
	TreePath     string
	CommitID     string
	RepoLink     string
	CloneLink    repoutil.CloneLink
	CommitsCount int64
}

func RepoRef(c *gin.Context) {

	var (
		refName string
		err     error
		Repo    = &Repository{}
	)

	repoPath := path.Join(config.Conf.Dir, c.Param("username"), c.Param("reponame")+".git")
	Repo.GitRepo, err = git.Open(repoPath)
	if err != nil {
		c.JSON(500, err.Error())
		return
	}

	// Get default branch.
	if c.Param("path") == "" {
		refName, err = getDefaultBranch(repoPath)
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		//refName = "master"
		if !Repo.GitRepo.HasBranch(refName) {
			_, err := Repo.GitRepo.Branches()
			if err != nil {
				c.JSON(500, err.Error())
				return
			}
			refName = config.Conf.DefaultBranch
		}
		Repo.Commit, err = Repo.GitRepo.BranchCommit(refName)
		if err != nil {
			//get branch commit
			c.JSON(500, err.Error())
			return
		}
		Repo.CommitID = Repo.Commit.ID.String()
		Repo.IsViewBranch = true

	} else {
		hasMatched := false
		parts := strings.Split(c.Param("path"), "/")
		for i, part := range parts {
			refName = part
			if Repo.GitRepo.HasBranch(refName) ||
				Repo.GitRepo.HasTag(refName) {
				if i < len(parts)-1 {
					Repo.TreePath = strings.Join(parts[i+1:], "/")
				}
				hasMatched = true
				break
			}
		}
		if !hasMatched && len(parts[0]) == 40 {
			refName = parts[0]
			Repo.TreePath = strings.Join(parts[1:], "/")
		}

		if Repo.GitRepo.HasBranch(refName) {
			Repo.IsViewBranch = true

			Repo.Commit, err = Repo.GitRepo.BranchCommit(refName)
			if err != nil {
				c.JSON(500, "get branch commit")
				return
			}
			Repo.CommitID = Repo.Commit.ID.String()

		} else if Repo.GitRepo.HasTag(refName) {
			Repo.IsViewTag = true
			Repo.Commit, err = Repo.GitRepo.TagCommit(refName)
			if err != nil {
				//get tag commit
				c.JSON(500, err.Error())
				return
			}
			Repo.CommitID = Repo.Commit.ID.String()
		} else if len(refName) == 40 {
			Repo.IsViewCommit = true
			Repo.CommitID = refName

			Repo.Commit, err = Repo.GitRepo.CatFileCommit(refName)
			if err != nil {
				c.JSON(500, err.Error())
				return
			}
		} else {
			c.JSON(500, "not find")
			return
		}
	}
	Repo.BranchName = refName

	c.Set("Repo", Repo)
}

func getDefaultBranch(repoPath string) (string, error) {
	// 设置执行命令的工作目录
	cmd := exec.Command("git", "symbolic-ref", "HEAD")
	cmd.Dir = repoPath

	// 执行命令并获取输出结果
	output, err := cmd.Output()
	if err != nil {
		return "", err
	}
	result := strings.Split(string(output), "/")
	branch := result[len(result)-1]
	branch = strings.Replace(branch, "\n", "", -1)
	return branch, nil
}
